/* Transformable.js
 *
 * Copyright 2006, Tim Dwelle.
 *
 * Licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.  See
 * the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

$package("dowry.widget");

/**
 * The Transformable module allows for the transformation
 * of collections (either arrays or maps) so they can be
 * consumed by a widget's <code>addValues()</code> method.
 * This may be necessary if the data in the collection is
 * not properly formatted, if a calculation needs to be
 * performed on the data, etc.
 *
 */
$mixin("Transformable").$as(
{
   /**
     * Sometimes the values passed in to
     * <code>addValues()</code> will not be a properly
     * formatted array of data.  This function, along with
     * <code>transformValue()</code>, provides a hook to
     * perform the necessary data conversions to the
     * expected format.
     *
     * <p>
     * If an array of data is passed in, each element
     * will be converted according to <code>transformValue()
     * </code>. If a map of data is passed in, each value &
     * key will be converted according to <code>
     * transformValue()</code> and the results will be
     * placed in an array.  So, unless you wish to alter the
     * fundamental semantics of the <code>transform()</code>
     * method, you usually can just override <code>
     * transformValue()</code>.
     * </p>
     *
     * @param vals  the collection to be transformed
     *
     * @return      the collection as a properly transformed
     *              array
     *
     */
    transform : function(vals)
    {
        var arr = null;

        if (vals != null)
        {
            // array
            if (vals.join)
            {
                for (var i=0; i < vals.length; i++)
                {
                    if (arr == null)
                    {
                        arr = new Array();
                    }

                    arr[arr.length] = this.transformValue(vals[i]);
                }
            }

            // map (be careful... since this will
            // really catch *any* js datatype)
            else
            {
                for (var key in vals)
                {
                    if (arr == null)
                    {
                        arr = new Array();
                    }

                    arr[arr.length] = this.transformValue(vals[key], key);
                }
            }
        }

        return arr;
    },

    /**
     * Sometimes the values passed in to <code>addValues()
     * </code> will not be a properly formatted array of
     * data.  This function performs the necessary data
     * conversion on a specified collection element to the
     * expected format.
     *
     * <p>
     * This default implementation simply returns the
     * value that was passed in.  Subclasses should override
     * this function with any custom transformation logic.
     * </p>
     *
     * @param val  the collection element to be transformed
     *
     * @param key  (optional) if the collection passed in
     *             was a map, then this will contain the
     *             key to which this collection element was
     *             bound
     *
     */
    transformValue : function(val, key)
    {
        return val;
    }
});